package store;

import java.sql.Connection; 
import java.sql.DriverManager; 
import java.sql.SQLException; 
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.PreparedStatement;
import java.sql.Blob;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import java.util.Enumeration;
import java.sql.Date;
import java.util.Hashtable;
import java.util.TreeMap;
import java.lang.Integer;
import java.io.*;

import index.Balise;
import index.DocumentAIndexer;
import index.PositionDoc;
import index.Term;
import index.TermFrequency;



/**
 * Cette classe permet de lire la BD relationnelle contenant l'index
 * Tables pouvant etre lues: Documents, Noeuds, Termes, PositionDoc, 
 */


public class BaseReader { 
        
         static Connection conn;
      
      
     /**
     * Constructeur. <br>
     * Effectue une connection a la base
     * @param ConnectURL String contenant l'URL pour la connection. Ex : jdbc:mysql://localhost:3306/databasename
     * @param login Login pour la connection a la BD
     * @param pass Password pour la connection a la BD
     */
         public BaseReader(String ConnectURL, String login, String pass) {
             
         try { 
            // The newInstance() call is a work around for some 
            // broken Java implementations
        	 Class.forName("org.postgresql.Driver").newInstance(); 
             System.out.println("Driver charge.");
             } catch (Exception ex) { 
            // handle the error 
         } 
        
        try {
             System.out.println("Tentative de connection..."); 
             conn = DriverManager.getConnection(ConnectURL,login,pass);
             System.out.println("Connection ok!");  
            
        }
        catch (SQLException ex) {
            // handle any errors 
            System.out.println("SQLException: " + ex.getMessage()); 
            System.out.println("SQLState: " + ex.getSQLState()); 
            System.out.println("VendorError: " + ex.getErrorCode()); 
        }
             
     } // BaseReader()
     
	 
	 
	 

	 
	 
    /**
    * Trouve un objet DocumentAIndexer correspondant a un id
    * @param id l'identifiant du doc
    * @return DocumentAIndexer objet DocumentAIndexer
    * @see DocumentAIndexer
    */
    public DocumentAIndexer document(int iddoc) throws SQLException{
        
       DocumentAIndexer myDocument = new DocumentAIndexer(); 
       //Statement stmt = null; 
       PreparedStatement stmt = null;
       ResultSet rs = null;
       String query = "select * from Documents where doc_id=?"; 
       stmt = conn.prepareStatement(query);        
       //String query = "select * from Documents where doc_id="+iddoc; 
       stmt.setInt(1, iddoc);
       //rs=stmt.executeQuery(query);
       rs=stmt.executeQuery();
       while (rs.next())
       {
               myDocument.name = rs.getString("document");
              
       }       
           if (stmt != null) { 
        try { 
            stmt.close(); 
        } catch (SQLException sqlEx) { // ignore
        } 

        stmt = null; 
    } //stmt 
       
       
       return myDocument;
       
    } //document()
    
    
    /**
     * Trouve un objet Balise correspondant a un idbalise
     * @param idbalise l'identifiant de la balise
     * @return Balise objet Balise
     * @see Balise
     */
     public Balise getBalise(int idbalise) throws SQLException{
    	Balise myBalise = null;
    	 
    	PreparedStatement stmt = null;
        ResultSet rs = null;
        
        String query = "select * from Balises where bal_id=?"; 
        stmt = conn.prepareStatement(query);        
       
        stmt.setInt(1, idbalise);
        rs=stmt.executeQuery();
        
        while (rs.next())
        {
        	myBalise = new Balise(idbalise, rs.getString("nom"), rs.getDouble("coeff"));
        }       
            if (stmt != null) { 
         try { 
             stmt.close(); 
         } catch (SQLException sqlEx) { // ignore
         } 

         stmt = null; 
     } //stmt 
        
        
        return myBalise;
        
     } //Balise()
     
     /**
      * Renvoie l'ensemble des Balises
      * @param idbalise l'identifiant de la balise
      * @return Balise objet Balise
      * @see Balise
      */
      public TreeMap<Integer, Balise> getBaliseTable() throws SQLException{
     	TreeMap<Integer, Balise> myBalises = new TreeMap<Integer, Balise>();
     	 
     	PreparedStatement stmt = null;
         ResultSet rs = null;
         
         String query = "select * from Balises"; 
         stmt = conn.prepareStatement(query);        
         rs=stmt.executeQuery();
         
         while (rs.next())
         {
         	myBalises.put(rs.getInt("bal_id"), new Balise(rs.getInt("bal_id"), rs.getString("nom"), rs.getDouble("coeff")));
         }       
             if (stmt != null) { 
          try { 
              stmt.close(); 
          } catch (SQLException sqlEx) { // ignore
          } 

          stmt = null; 
      } //stmt 
         
         
         return myBalises;
         
      } //Balise()
     
     /**
      * Crée une liste d'objet positionDoc pour un idterm et un iddoc
      * @param idterm l'identifiant du term
      * @param iddoc l'identifiant du doc
      * @return List<PositionDoc> Liste d'objets PositionDoc
      * @see PositionDoc
      */
      public List<PositionDoc> getPositionDocFromDoc(int idterm, int iddoc) throws SQLException{
     	List<PositionDoc> myList = new ArrayList<PositionDoc>();
     	 
     	PreparedStatement stmt = null;
         ResultSet rs = null;
         
         String query = "select * from PositionDoc where term_id=? and doc_id=?"; 
         stmt = conn.prepareStatement(query);        
        
         stmt.setInt(1, idterm);
         stmt.setInt(2, iddoc);
         rs=stmt.executeQuery();
         
         while (rs.next())
         {
         	PositionDoc posdoc = new PositionDoc(rs.getInt("pos_id"), iddoc, idterm,rs.getInt("position"), rs.getInt("bal_id"));
         	myList.add(posdoc);
         }       
             if (stmt != null) { 
          try { 
              stmt.close(); 
          } catch (SQLException sqlEx) { // ignore
          } 

          stmt = null; 
      } //stmt 
         
         
         return myList;
         
      } //getPositionDocFromDoc()
	      
      /**
       * Crée une liste d'objet positionDoc pour un idterm
       * @param idterm l'identifiant du term
       * @return List<PositionDoc> Liste d'objets PositionDoc
       * @see PositionDoc
       */
       public List<PositionDoc> getPositionDoc(int idterm) throws SQLException{
      	List<PositionDoc> myList = new ArrayList<PositionDoc>();
      	 
      	PreparedStatement stmt = null;
          ResultSet rs = null;
          
          String query = "select * from PositionDoc where term_id=?"; 
          stmt = conn.prepareStatement(query);        
         
          stmt.setInt(1, idterm);
          
          rs=stmt.executeQuery();
          
          while (rs.next())
          {
          	PositionDoc posdoc = new PositionDoc(rs.getInt("pos_id"), rs.getInt("doc_id"), idterm,rs.getInt("position"), rs.getInt("bal_id"));
          	myList.add(posdoc);
          }       
              if (stmt != null) { 
           try { 
               stmt.close(); 
           } catch (SQLException sqlEx) { // ignore
           } 

           stmt = null; 
       } //stmt 
          
          
          return myList;
          
       } //getPositionDoc()

       
       /**
        * Renvoie un coefficient pour une positionDoc
        * @param idpos l'identifiant de la position
        * @return double coeff
        * @see PositionDoc,Balise
        */
        public double getCoeff(int idpos) throws SQLException{
       	double coeff = 0;
       	 
       	PreparedStatement stmt = null;
           ResultSet rs = null;
           
           String query = "select coeff from PositionDoc P, Balises B where P.bal_id=B.bal_id and pos_id=?"; 
           stmt = conn.prepareStatement(query);        
          
           stmt.setInt(1, idpos);
           
           rs=stmt.executeQuery();
           
           while (rs.next())
           {
           	coeff = rs.getDouble("coeff"); 
           }       
               if (stmt != null) { 
            try { 
                stmt.close(); 
            } catch (SQLException sqlEx) { // ignore
            } 

            stmt = null; 
        } //stmt 
           
           
           return coeff;
           
        } //getCoeff()
     
     /**
     * Trouve l'objet Term correspondant a un terme en le cherchant dans la table Termes
     * @see Term
     * @param termName nom du terme a chercher
     * @return Term Object Term correspondant a la chaine a rechercher
     */
     public Term  readTerm(String termName) throws SQLException{   
        
         // assume conn is an already created JDBC connection
       /*Statement stmt = null; 
       Statement stmt2 = null;*/
       PreparedStatement stmt = null;
       PreparedStatement stmt2 = null;
       ResultSet rs = null;
       
       //System.out.println("on recherche le terme :"+ termName);
       
       String query = "select * from Termes where term=?";
       stmt = conn.prepareStatement(query); 
       
       String query2 = "select * from TermesDoc where term_id=?";
	   stmt2 =conn.prepareStatement(query2);
	  
       /*stmt = conn.createStatement(); 
       stmt2 = conn.createStatement();*/ 
       //String query = "select * from Termes where term=\'"+termName+"\';";
       
       Term myTerm=null; 
       TreeMap tableFrequency = new TreeMap();
       stmt.setString(1, termName);
       //rs = stmt.executeQuery(query);
       rs = stmt.executeQuery();
       while (rs.next())
       {	
    		 
             int term_id = rs.getInt("term_id");
             stmt2.setInt(1,term_id);
             //String query2 = "select * from TermesDoc where term_id="+term_id+";";  
             ResultSet rs2 = null;
             //rs2 = stmt2.executeQuery(query2);
             rs2 = stmt2.executeQuery();
              // for each doc in which the term is
                
             while (rs2.next())
                {
                	   int doc_id = rs2.getInt("doc_id");  //  get the node doc id
                	   short frequency = rs2.getShort("poids");	 // get frequency 
                	  // System.out.println("terme présent dans "+this.document(doc_id).name+" de poids "+frequency);
                        TermFrequency myTermFrequency= new TermFrequency(doc_id, frequency);
                        tableFrequency.put(doc_id, myTermFrequency);
                        
                }
             
             List<PositionDoc> posDoc = getPositionDoc(term_id);
        
            myTerm = new Term(term_id, termName, tableFrequency, posDoc); 
       } //while rs.next

       if (stmt != null) { 
        try { 
            stmt.close(); 
        } 
        catch (SQLException sqlEx) { // ignore
        } 
        stmt = null; 
       	} //stmt 
       return myTerm;

       
     } //readTerm()
    


     
     
/**
* Ferme la connection au serveur MySQL
*/
public static void close() {
     try {
          conn.close();     
           
        } catch (SQLException ex) {
            // handle any errors 
            System.out.println("SQLException: " + ex.getMessage()); 
            System.out.println("SQLState: " + ex.getSQLState()); 
            System.out.println("VendorError: " + ex.getErrorCode()); 
        }   
} //close()
     
     
     
     
}// BaseReader.java
